package dabs.engine.plant;

import static org.junit.Assert.*;

import java.util.ArrayList;


import org.junit.Before;
import org.junit.Test;
import dabs.engine.DummyInterface;
import dabs.engine.control.ComponentCommand;
import dabs.engine.control.OperatorSoftware;
import dabs.engine.environment.Environment;
import dabs.engine.environment.TemporaryDisable;
import dabs.engine.exceptions.ComponentNotFoundException;


public class PowerPlantTest {

	DummyInterface dinterface;
	Environment environment;
	PowerPlant powerplant;
	TemporaryDisable modifier;
	OperatorSoftware opSoft;
	ComponentCommand command;
	
		
	@Before
	public void setUp() throws Exception {
		dinterface = new DummyInterface();
		powerplant = new PowerPlant(dinterface);
		environment = new Environment(dinterface, powerplant, 30, 30);
		opSoft = new OperatorSoftware(dinterface, powerplant);
	}

	
	@Test
	public void testKillingComponentsThatCanBeDisabled() {
		ArrayList<String> args = new ArrayList<String>();	
		args.add("close");
		
		
		//kill all the Components that can be Disabled, except Valves
		for (ComponentPart comp : powerplant.getComponents()) {
			if (comp instanceof Condenser || comp instanceof Pump || comp instanceof Reactor) {
				comp.setHealth(0);
				dinterface.get().getDescription();				
			}
		}
		environment.generateDisable(10);
		//clear the Notiffications
		dinterface.makeEmpty();			
		
		//check if generateDisable now only disables Valves, as other components
		//that could be disabled are now dead
		for(int i=0; i<100; i++){
			
			environment.generateDisable(10);
			assertTrue(dinterface.get().getDescription().contains("valve"));			
		}
			
		dinterface.makeEmpty();
		//generateDisable, then kill all the valves to make sure that the one which was
		//supposed to get it would die, and try running commands on them, and check that 
		//commands don't produce "stalling" message
		environment.generateDisable(10);
		
		for (ComponentPart comp : powerplant.getComponents()) {
			if (comp instanceof Valve) {
				comp.setHealth(0);
				command = new ComponentCommand(comp.getName(),args);
				comp.runCommand(command);
				}} 
		for(int i=0; i<30; i++){powerplant.tick();};
		
		assertFalse(dinterface.toString().toLowerCase().contains("Stalling"));
		environment.generateDisable(10);		
	}
	
	
	@Test 
	public void testHealth(){
			
		for(ComponentPart comp : powerplant.getComponents()){
		assertEquals(comp.getHealth(), 1000);
			assertFalse(comp.isDead());
			comp.setHealth(10);
			assertEquals(comp.getHealth(), 10);
			dinterface.makeEmpty();
			comp.setHealth(-1000);
			//if more damage then health left should simply die (i.e. health =0).
			assertTrue(dinterface.get().getDescription().contains("destroyed"));
			assertEquals(comp.getHealth(), 0);
			assertTrue(comp.isDead());
			comp.setHealth(10);
			assertEquals(comp.getHealth(), 0);				
		}
		
		
	} 
		

		
	@Test
	public void testModifiers(){
		 for (ComponentPart comp : powerplant.getComponents()) {
			if (comp instanceof Condenser || comp instanceof Pump || comp instanceof Reactor || comp instanceof Valve) {
		
				modifier = new TemporaryDisable(2);		
		comp.handleModifier(modifier);
		assertTrue(comp.isDeactivated());
		assertTrue(dinterface.get().getDescription().contains("Stalling"));
		comp.tick();
		assertTrue(comp.isDeactivated());
		comp.tick();
		assertFalse(comp.isDeactivated());	//deactivation time set to 2 ticks, after that comp becomes active again
		assertTrue(dinterface.get().getDescription().contains("active again"));
		comp.handleModifier(modifier);
		comp.tick();
		comp.handleModifier(modifier);
		comp.tick();
		comp.tick();
		assertTrue(comp.isDeactivated());   // if comp gets two modifiers to be deactivated in a row - it adds them, and stays deactivated longer
		comp.setHealth(0);
		dinterface.makeEmpty();
		comp.tick();
		comp.tick();
		comp.tick();
		assertFalse(dinterface.toString().contains("active again"));		
		dinterface.makeEmpty();
	}	}	}
	

	@Test
	public void testIfResponsiveWhenDead() throws ComponentNotFoundException{
		ArrayList<String> args = new ArrayList<String>();		
		ArrayList<String> args2 = new ArrayList<String>();		
		ArrayList<String> args3 = new ArrayList<String>();		
		ArrayList<String> args4 = new ArrayList<String>();
		
		
		for(ComponentPart comp : powerplant.getComponents()){
			
			if(comp instanceof Reactor||comp instanceof Pump||comp instanceof Condenser){
				args.add("30");
			//set the components to have 30 health
				
				command = new ComponentCommand(comp.getName(), args);
					try {
					opSoft.runCommand(command);
					} catch (Exception e) {}				
				assertTrue(comp.read().toString().contains("30"));				
				//try killing the components and running commands on them
				comp.setHealth(0);
				args2.add("90");
				command = new ComponentCommand(comp.getName(), args2);				
					try {
					opSoft.runCommand(command);
					} catch (Exception e) {}
					//check if comands weren't implemented
					assertFalse(comp.read().toString().contains("90"));
			}
			
			if(comp instanceof Valve){
				args3.add("open");
				command = new ComponentCommand(comp.getName(), args3);
					try {
					opSoft.runCommand(command);
					} catch (Exception e) {}				
				assertTrue(comp.read().toString().contains("open"));				
				comp.setHealth(0);
				args4.add("close");
				command = new ComponentCommand(comp.getName(), args4);				
					try {
					opSoft.runCommand(command);
					} catch (Exception e) {}
					assertFalse(comp.read().toString().contains("closed"));
				}
			}
	
		}	
}
